package br.edu.ufcg.splab.io;

import static org.junit.Assert.assertTrue;

import org.junit.Test;

import br.edu.ufcg.splab.core.graph.Graph;
import br.edu.ufcg.splab.exceptions.ParseException;

public class TGFParserTest {

	@Test
	public void testSimpleGraph() {
		try {
			//This tgf is valid, with endline at each line end. Two vertexes and two edges, one of these edges are a auto loop.
			String tgfWithEndLineChar = "./test-data/input/tgfWithEndLine.tgf";
			TGFParser parser = new TGFParser();
			Graph graph = parser.parseTGF(tgfWithEndLineChar);
			assertTrue(graph.getEdges().size() == 2);
			assertTrue(graph.getRoot().getLabel().equals("0"));
			assertTrue(graph.getStates().size() == 2);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Test
	public void testComplexGraph() {
		try {
			//This tgf is valid, with endline at each line end. Twenty five vertexes and thirty edges.
			String greatestTGFWithEndlines = "./test-data/input/greatestTGFWithEndlines.tgf";
			TGFParser parser = new TGFParser();
			Graph graph = parser.parseTGF(greatestTGFWithEndlines);
			assertTrue(graph.getEdges().size() == 30);
			assertTrue(graph.getRoot().getLabel().equals("0"));
			assertTrue(graph.getStates().size() == 25);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Test
	public void testInvalidNoHashGraph() {
		try {
			//This tgf is invalid, with endline at each line end and without a hash ("#") symbol. Two vertexes and two edges.
			String tgfWithoutHashEndLine = "./test-data/input/tgfWithoutHashEndLine.tgf";
			TGFParser parser = new TGFParser();
			Graph graph = parser.parseTGF(tgfWithoutHashEndLine);
		} catch (ParseException e) {
			assertTrue(e.getMessage().equals("The TGF file must have a \"#\" separating the nodes and edges definition."));
		}
	}
	
	@Test
	public void testInvalidDifferentNodeIds() {
		try {
			//This tgf is invalid, with different node ids at some node (line 5 precisely). Twenty five vertexes and thirty edges.
			String greatestTGFDifferentNodeIds = "./test-data/input/greatestTGFDifferentNodeIds.tgf";
			TGFParser parser = new TGFParser();
			Graph graph = parser.parseTGF(greatestTGFDifferentNodeIds);
		} catch (ParseException e) {
			assertTrue(e.getMessage().equals("In the definition of the node 5, the values must be equal."));
		}
	}
	
	@Test
	public void testInvalidNoDefinedNodeId() {
		try {
			//This tgf is invalid, with a edge referring a non defined vertex (line 40 precisely). Twenty five vertexes and thirty edges.
			String greatestTGFNoRelatedVertex = "./test-data/input/greatestTGFNoRelatedVertex.tgf";
			TGFParser parser = new TGFParser();
			Graph graph = parser.parseTGF(greatestTGFNoRelatedVertex);
		} catch (ParseException e) {
			assertTrue(e.getMessage().equals("In the definition of the edge 14, the node 100 must be defined previously."));
		}
	}
	
	@Test
	public void testNaNVertexLabel() {
		try {
			//This tgf is invalid, with a vertex definition with a word and not a number (line 6 precisely). Twenty five vertexes and thirty edges.
			String greatestTGFErrorInVertexLabel = "./test-data/input/greatestTGFErrorInVertexLabel.tgf";
			TGFParser parser = new TGFParser();
			Graph graph = parser.parseTGF(greatestTGFErrorInVertexLabel);
		} catch (ParseException e) {
			assertTrue(e.getMessage().equals("In the definition of the node 6, the values must be two integer numbers."));
		}
	}
	
	@Test
	public void testThreeRoots() {
		try {
			//This tgf is invalid, with three roots. Twenty five vertexes and thirty edges.
			String greatestThreeRoots = "./test-data/input/greatestThreeRoots.tgf";
			TGFParser parser = new TGFParser();
			Graph graph = parser.parseTGF(greatestThreeRoots);
		} catch (ParseException e) {
			String message = e.getMessage();
			assertTrue(message
					.contains("The graph contains more than one root node:")
					&& message.contains("0")
					&& message.contains("40")
					&& message.contains("41")
					&& message.contains("Just the first node defined in the file must be the root."));
		}
	}
	
	@Test
	public void testDisconnectedNodes() {
		try {
			//This tgf is invalid, with three roots. Twenty five vertexes and thirty edges.
			String greatestDisconnectedNodes = "./test-data/input/greatestDisconnectedNodes.tgf";
			TGFParser parser = new TGFParser();
			Graph graph = parser.parseTGF(greatestDisconnectedNodes);
		} catch (ParseException e) {
			String message = e.getMessage();
			assertTrue(message
					.contains("The graph contains at least one disconnected node:")
					&& message.contains("40")
					&& message.contains("41")
					&& message.contains("The graph cannot contain disconnected nodes."));
		}
	}
	
	@Test
	public void testHugeTGF() {
		try {
			String blinkerN = "./test-data/input/BlinkerN.tgf";
			TGFParser parser = new TGFParser();
			Graph graph = parser.parseTGF(blinkerN);
			assertTrue(graph.getRoot().getLabel().equals("0"));
			assertTrue(graph.getStates().size() == 64);
			assertTrue(graph.getEdges().size() == 259);
		} catch (ParseException e) {
			
		}
	}
	
}
